// === uuHash ===
// depend: uuMeta
/*
uuMeta.pair(key, value) - return { key: value }
uuMeta.size(mix) - return mix.length
uuMeta.first(mix, miss) - return mix.first element
uuMeta.last(mix, miss) - return mix.last element
uuMeta.keys(mix) - return Array( [key1, key2, ...] )
uuMeta.values(mix) - return Array( [value1, value2, ...] )
 */
(function() {
var _hash; // inner namespace

_hash = {
  // uuMeta.pair - make one pair Hash( { key: value } )
  pair: function(key,     // @param String/Number: hash-key
                 value) { // @param Mix: hash-value
                          // @return Hash: { key: value }
    var rv = {};

    rv[key] = value;
    return rv;
  },

  // uuMeta.size - get hash length
  size: function(mix) {   // @param FakeArray/Array/Hash:
                          // @return Number:
    return fn(mix, 0);
  },

  // uuMeta.first - get first element value
  first: function(mix,    // @param FakeArray/Array/Hash:
                  miss) { // @param Mix(= undefined): miss value
                          // @return Mix:
    return fn(mix, 1, miss);
  },

  // uuMeta.last - get last element value
  last: function(mix,     // @param FakeArray/Array/Hash:
                 miss) {  // @param Mix(= undefined): miss value
                          // @return Mix:
    return fn(mix, 2, miss);
  },

  // uuMeta.keys - enum index
  keys: function(mix) {   // @param FakeArray/Array/Hash:
                          // @return Array: [key, ... ]
    return fn(mix, 3);
  },

  // uuMeta.values - enum values
  values: function(mix) { // @param FakeArray/Array/Hash:
                          // @return Array: [value, ... ]
    return fn(mix, 4);
  }
};

function fn(mix, _kind, _miss) {
  var rv = [], ri = -1, v = _miss, i, iz, size = 0;

  if ("length" in mix) { // FakeArray / Array
    for (i = 0, iz = mix.length; i < iz; ++i) {
      if (i in mix) {
        ++size, v = mix[i];
        if (_kind === 1) {
          break;
        }
        if (_kind >= 3) {
          rv[++ri] = _kind === 3 ? i : v;
        }
      }
    }
  } else {
    for (i in mix) { // Object
      if (mix.hasOwnProperty(i)) {
        ++size, v = mix[i];
        if (_kind === 1) {
          break;
        }
        if (_kind >= 3) {
          rv[++ri] = _kind === 3 ? i : v;
        }
      }
    }
  }
  return !_kind ? size : (_kind >= 3) ? rv : v;
}

// --- initialize ---

// --- export ---
uuMeta.mix(uuMeta, _hash); // uuMeta

})(); // uuHash scope

